import java.util.*;
import java.io.*;
/**
 * Creates comments and keywords in the LaTeX format.
 * 
 * @author James Stanier
 */
public class InDepthToLaTeX {

	private ArrayList<CommentToken> comments;
	private ArrayList<LaTeXCommentToken> translatedComments;
	private String fileName;
	private CommentTranslator translator;
	private ArrayList<KeywordToken> keywords;
	private String translatedKeywords;
	private int sectionNumber;
	private String variables;
	private int arrayPosition;
	private int prevPos;
	private boolean firstPass;

	/**
	 * Constructor.
	 * @param c The array of comment tokens for the input file.
	 * @param f The input file name.
	 * @param v List of variables.
	 */
	public InDepthToLaTeX(ArrayList<CommentToken> c, String f, String v) {
		firstPass = true;
		translatedComments = new ArrayList<LaTeXCommentToken>();
		translatedKeywords = "";
		comments = c;
		fileName = f;
		sectionNumber = 1;
		variables = v;
		arrayPosition = 0;
		keywords = new ArrayList<KeywordToken>();
	}

	/**
	 * Translates comments and stores keywords in an array.
	 * @throws Exception
	 */
	public void prepareOutput() throws Exception {

		for(int i = 0; i < comments.size(); i++) {
			String output = "";
			CommentToken ct = comments.get(i);
			translator = new CommentTranslator(ct.getComment());
			translator.translate();
			
			if(firstPass) {
				
				// Trim name from absolute path
				String longFileName = JavaParser.getFileName();
				int counter = 0;
				char c = System.getProperty("file.separator").toCharArray()[0];
				for(int j = longFileName.length()-1; j >=0; j--) {
					counter = j;
					if(longFileName.charAt(j) == c) {
						break;
					}
				}
				
				longFileName = longFileName.substring(counter+1);
				
				
				firstPass = false;
				output += "\\newpage\n\\section{In-depth commenting for \\textsf{" + longFileName + "}}\n";
			}

			if(arrayPosition == 0) {
				prevPos = 0;
			}
			else {
				prevPos = arrayPosition;
			}

			int oldSize = keywords.size();
			keywords.addAll(translator.getKeywords());
			arrayPosition = translator.getKeywords().size() + oldSize;

			if(translator.isOpen()) {

				for(int j = prevPos; j < arrayPosition; j++) {
					keywords.get(j).addSectionNumber(((Integer)sectionNumber).toString());
				}
				
				output += "\\hrulefill\\newline\\textbf{Section " + sectionNumber++;

				if(translator.getTitle() != null) {
					output += ": " + "\\textit{" + translator.getTitle() + "}";
				}
				output += "}\\\\\\\\\n";

				String s = translator.getOutput();
				if(s.contains("\\n")) {
					s.replace("\\n", " ");
				}
				else if(s.contains("\r")) {
					s.replace("\\r", " ");
				}
				output += s + "\n";

				translatedComments.add(new LaTeXCommentToken(output, true, 
						ct.getParent(), ct.getLineNumber(), sectionNumber, translator.getKeywords()));
			}
			else {

				for(int j = prevPos; j < arrayPosition; j++) {
					int temp = sectionNumber-1;
					keywords.get(j).addSectionNumber(((Integer)temp).toString());
				}

				if(i < comments.size()-1) { 
					output += translator.getOutput() + "\n\n";
				}
				else {
					output += translator.getOutput() + "\n";
				}
				translatedComments.add(new LaTeXCommentToken(output, false, 
						ct.getParent(), ct.getLineNumber(), sectionNumber, translator.getKeywords()));
			}
		}

		// Arrange keyword array
		ArrayList<KeywordToken> sortedkw = new ArrayList<KeywordToken>();
		ArrayList<String> uniquekw = new ArrayList<String>();
		for(int i = 0; i < keywords.size(); i++) {
			if(!uniquekw.contains(keywords.get(i).getKeyword())) {
				uniquekw.add(keywords.get(i).getKeyword());
			}
		}	

		while(!keywords.isEmpty()) {
			for(int i = 0; i < uniquekw.size(); i++) {
				KeywordToken k = new KeywordToken(uniquekw.get(i));
				for(int j = 0; j < keywords.size(); j++) {
					if(keywords.get(j).getKeyword().equals(k.getKeyword())) {
						k.addSectionNumber(keywords.get(j).getSectionNumbers());
						keywords.remove(j);
						j--;
					}
				}
				sortedkw.add(k);
			}
		}
		
		keywords = sortedkw;

	}

	/**
	 * Get the translated comments.
	 * @return Array of translated comments.
	 */
	public ArrayList<LaTeXCommentToken> getTranslatedOutput() {
		return translatedComments;
	}

	/**
	 * Get the list of declared keywords in a comment.
	 * @return Declared keywords for this comment.
	 */
	public ArrayList<KeywordToken> getKeywords() {
		return keywords;
	}

	/**
	 * Creates the keyword index section.
	 * @return The keyword index section in LaTeX.
	 */
	public String getTranslatedKeywords() {
		
		Collections.sort(keywords);
		
		// Trim name from absolute path
		String longFileName = JavaParser.getFileName();
		int counter = 0;
		char c = System.getProperty("file.separator").toCharArray()[0];
		for(int j = longFileName.length()-1; j >=0; j--) {
			counter = j;
			if(longFileName.charAt(j) == c) {
				break;
			}
		}
		
		longFileName = longFileName.substring(counter+1);
		
		translatedKeywords += "\\subsection{Keyword index for \\textsf{"+ longFileName + "}}\n" +
		"The keyword index contains a list of all defined keywords in " +
		"in-depth comments, with the number of the section they appear in.\n\n";

		for(int i = 0; i < keywords.size(); i++) {
			translatedKeywords += "\\textbf{" + keywords.get(i).getKeyword() + "}, " 
			+ keywords.get(i).getSectionNumbers() + "\\\\\n";
		}

		return translatedKeywords;
	}

}
